package com.yy.micro.magic.core.context;

import com.yy.micro.magic.core.loader.impl.PlanScheduleResourceLoader;
import com.yy.micro.magic.core.model.PlanSchedule;
import com.yy.micro.magic.core.provider.ResourceProviderFactory;
import com.yy.micro.magic.ext.domain.filter.DynamicTrigger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

/**
 * @author YY
 * @version 1.0.0
 * @update 2021/9/18 9:26 下午
 * @description: Magic Cude数据变换的上下文，包含了变换过程中需要的各种资源和组件。原则上下文中的资源在变换过程中只读，如果需要修改，则建议clone对象中修改。
 */
@Component
public class MagicCubeContext {

    @Autowired
    private ResourceManager manager;

    @Autowired
    private ResourceProviderFactory factory;

    @Autowired
    private Environment environment;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private ComponentManager componentManager;

    public ComponentManager getComponentManager() {
        return componentManager;
    }

    public ResourceManager getManager() {
        return manager;
    }

    /**
     * @param planCode 数据变换规则的{@link PlanSchedule}的唯一业务标识
     * @return {@link PlanSchedule} 数据变换规则集
     * @description: 根据planCode查找数据变换规则的PlanSchedule，先在静态配置资源中查找，如果没有找到，则到扩展资源提供器中查找（如数据库）
     * @update 2021/9/18
     */
    public PlanSchedule findPlanSchedule(String planCode) {
        PlanSchedule schedule = manager.getValue(PlanScheduleResourceLoader.class, planCode, PlanSchedule.class);
        if (null == schedule) {
            schedule = factory.findPlanSchedule(planCode);
        }
        return schedule;
    }

    /**
     * @param planCode  数据变换规则的唯一业务标识
     * @param condition 数据变换中的数据条件，即源数据中某一数据的全路径，如：aaaa#gg-0#code，与@link DynamicTrigger}中定义的"trigger"正则匹配
     * @return {@link DynamicTrigger}
     * @description: 查找动态数据变换规则的触发器。数据变换中List类型的数据在size上存在未知，无法在变换规则中穷举，通过动态规则触发器的正则功能，可以很好的解决这一总是。
     * @update 2021/9/18
     */
    public DynamicTrigger findFilterCondition(String planCode, String condition) {
        return factory.findDynamicTrigger(planCode, condition);
    }

    /**
     * @description: 获取资源提供工厂
     * @return {@link ResourceProviderFactory}
     * @update 2021/9/18
    */
    public ResourceProviderFactory getFactory() {
        return factory;
    }

    public Environment getEnvironment() {
        return environment;
    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }
}
